const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssets = require('optimize-css-assets-webpack-plugin')
const { default: postcss } = require('postcss')
const postcssConfig = require('./config/postcss.config.js')
/***************** 使用 dependOn 来分割带代码
  注释
    利用dependOn 来分割带代码，
    将多个入口的都引用的第三方插件打包在一个文件内，
    然后在各个入口内就不会有被提取出去的代码了，
    可以分割公共代码
  module.exports = {
    mode:'production',
      entry:{
        index:{
          import:'./src/index.js',
          dependOn:"vue-vendors"
        },
        "vue-vendors":['vue','vue-router','vuex']
      },
    entry: {

    },
    output:{
      filename:'[name].js',
      path:path.resolve(__dirname, "./dist")
    },
    plugins:[
      new CleanWebpackPlugin()
    ]
  }
******************/

/* ******************** 多种配置
注释:
  导出多种配置，用name来命名不同的配置。
  配置间可以进行组合

  思考：可以把多页面内容单独为每一个页面配置一个'导出',
    实现开发时，对一个其中一个页面开发不影响其他的页面。
    打包时，针对修改的页面进行打包没有修改的页面不参与打包
  module.exports = [
    {
          mode:'production',
          name:"test1",
          entry: {
              index: { import: './src/index.js', dependOn: 'vue-vendors' },
              'vue-vendors': ['vue', 'vue-router', 'vuex']
          },
          output: {
              filename: '[name].js',
              publicPath: path.resolve(__dirname, 'dist')
          },
          plugins:[
            new CleanWebpackPlugin()
          ]
      },
      {
          mode:'production',
          name:"test2",
          entry: {
              main: { import: './src/index.js'},
          },
          output: {
              filename: '[name].js',
              publicPath: path.resolve(__dirname, 'dist')
          },
          plugins:[
            new CleanWebpackPlugin()
          ]
      }
  ]
module.exports.parallelism = 1; // 指定最大并发数
******************** */

/* ******************** 以函数形式返回
注释: 以函数形式返回
  配置为一个函数可以从外部接受参数
  可以使用一套代码接受不通的参数完成多种配置。
  npx webpack --env prod
  env :{pard:true}
  npx webpack --env prod=app
  env :{pard:'app'}
  npx webpack --env prod.name='ccc'
  env :{pard:{name:'ccc'}}
  module.exports = function(env, args) {
    console.log(env)// 参数一是环境
    console.log(args.mode)// 参数二是传递给 webpack 的配置项
      return {
          mode: 'production',
          name: "test2",
          entry: {
              main: { import: './src/index.js' },
          },
          output: {
              filename: '[name].js',
              publicPath: path.resolve(__dirname, 'dist')
          },
          plugins: [
              new CleanWebpackPlugin()
          ]
      }
  }
******************** */
console.log('mode=====================================', process.env.NODE_ENV)
module.exports = {
  // mode: 'production',
  mode: 'development',
  entry: {
    index: {
      import: './src/index.js',
      // dependOn: 'vue-vendors'
    },
    // 'vue-vendors': ['vue', 'vue-router', 'vuex', 'element-ui']
  },
  devServer: {
    contentBase: './dist', //将dist目录下的文件(index.html)作为可访问文件, 如果不写这个参数则默认与webpack.cofig.js的同级目录
    port: 8080 //端口号设为8080, 默认也是8080
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'js/[name]-[hash:6].js',
    // chunkFilename:'commt/[id].js'
    chunkFilename:(pathData) => {
      return 'commt/[id].js';
    },
    // publicPath:'./'
  },
  optimization: {
    splitChunks: {
      // include all types of chunks
      chunks: 'all',
      cacheGroups: {
        'vue-vendors': {
          name: 'chunk-vue-vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          chunks: 'async',
          enforce: true,
          reuseExistingChunk: true
        },
        commt: {
          name: 'chunk-commt',
          test: /[\\/]commt[\\/]/,
          priority: -10,
          chunks: 'async',
          enforce: true,
          reuseExistingChunk: true
        },
      }
    }
  },
  devtool: process.env.NODE_ENV !== 'production' ?
    'eval-cheap-module-source-map' : 'cheap-module-source-map',
  module: {
    rules: [{
        test: /\.css$/,
        // use: ['style-loader', 'css-loader'] // 不会分离css 但会直接写到js 文件里面
        /*use: [{ // 使用file-loader可以提取出css 但是没有在html文件引入
                            loader: 'file-loader',
                            options: {
                                name: '[name].[ext]',
                                emitFile: false,
                            },
                        }]*/
        use: [
          // 'style-loader',
          // 提出css 并且注入到html文件。
          process.env.NODE_ENV !== 'production' ?
          'vue-style-loader' :
          MiniCssExtractPlugin.loader,
          { loader: 'css-loader', options: { importLoaders: 1 } },
          {
            loader: 'postcss-loader',
            options: postcssConfig
          }
        ]
      },
      {
        test: /\.less$/,
        exclude: /node_modules/,
        use: [
          // 'style-loader',
          // 提出css 并且注入到html文件。
          process.env.NODE_ENV !== 'production' ?
          'vue-style-loader' :
          MiniCssExtractPlugin.loader,
          { loader: 'css-loader', options: { importLoaders: 1 } },
          { loader: 'less-loader' },
          {
            loader: 'postcss-loader',
            options: postcssConfig
          }
        ]
      },
      //解析el的文件
      {
        test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
        loader: 'file-loader'
      },
      {
        test: /\.vue$/,
        use: {
          loader: 'vue-loader'
        }
      },
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new VueLoaderPlugin(),
    // 生成html
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: './index.html',
      hash: true,
      inject: 'body'
    }),
    // css 抽离
    new MiniCssExtractPlugin({
      filename: 'css/[name]-[hash:6].css',
      linkType: false
    }),
    // 压缩css
    new OptimizeCssAssets({
      assetNameRegExp: /\.css$/g,
      cssProcessor: require('cssnano'),
      cssProcessorPluginOptions: {
        preset: ['default', { discardComments: { removeAll: true } }]
      },
      canPrint: true
    })
  ]
}
